<template>
    <div class="container">
      <!-- <div class="video-wrapper">
        <video ref="videoRef" muted autoplay></video>
        <div v-if="!hasVideoInput" class="tip">{{ tip }}</div>
        <div class="bottom-wrapper">
          <MicroButton :disabled="!hasAudioInput"  @open="openMicro" @close="closeMicro"/>
          <VideoButton :disabled="!hasVideoInput" @open="openVideo" @close="closeVideo"/>
        </div>
      </div> -->
      <div class="content">
          <div class="self">
            <div class="user">
              <video ref="videoRef" muted autoplay></video>
              <div v-if="!hasVideoInput" class="tip">{{ tip }}</div>
            </div>
          </div>
          <div class="member-list">
            <div class="member-item" v-for="item in memberList" :key="item.uuid">
              <video :id="`im_${item.uuid}`" playsinline muted autoplay></video>
            </div>
           
          </div>
         
          <div class="message-wrapper">
        <div class="msg-item" v-for="item in messageList" :key="item.id" >
          <span class="name">{{ item.name }}：</span>
          <span>{{ item.content }}</span>
        </div>
      </div> 
      </div>
      <div class="footer">
        <div class="left">
       
        </div>
        <div class="middle">
          <MicroButton :disabled="!hasAudioInput"  @open="openMicro" @close="closeMicro" />
          <VideoButton :disabled="!hasVideoInput" @open="openVideo" @close="closeVideo"/>
          <ScreenButton @open="openScreen" @close="closeScreen"/>
          <EmojiButton @on-change="handleEmoji"/>
          <TextInputButton @send-message="handleEmoji" />
          <div class="item hang-up" @click="hangup">
          <svg-icon name="icon-call-end" color="#fff"></svg-icon>
        </div>
        </div>
      </div>
     

    </div>
  
  </template>
  <script setup >
  import { ref } from 'vue';
   import MicroButton from './components/MicroButton.vue';
   import VideoButton from './components/VideoButton.vue';
   import ScreenButton from './components/ScreenButton.vue';
   import EmojiButton from './components/EmojiButton.vue';
   import TextInputButton from './components/TextInputButton.vue';
   import { useDevice} from './use-device'
   import socket from '../../../utils/socket';
import { useRoute } from 'vue-router';
import  Avatar  from './image.png';
import { getMemberListAPI } from '../../../api/meeting';
import { ElMessage } from 'element-plus';
   const route=useRoute()
   const remoteMember=ref(null)
   const remoteRef =ref()
   const memberList = ref([]);
   const messageList=ref([])
   const {openMicro,openVideo,closeMicro,closeVideo, hasVideoInput,hasAudioInput,videoRef,tip,openScreen,closeScreen, localeStream,
    initDevice} =useDevice()

  const username=ref('')

  function hangup() {
   
  socket.send('HANGUP', {"meetingId": route.query.meetingId});
}


 //peerConnection webRTC对等连接
  // let pc=null 
  const pcMap=new Map()

    const baseStream=new MediaStream()//用来做视频传输的业务
     async function init(){
      await initDevice()
      const { videoStream,audioStream,screenStream}=localeStream
      //把视频和音频的轨道做一个整合
      videoStream?.getTracks().forEach(track=>baseStream.addTrack(track))
      audioStream?.getTracks().forEach((track)=>baseStream.addTrack(track))
      
      const res=await getMemberListAPI(route.query.meetingId)
      const members=res.result
      console.log('members',members)
      memberList.value=members
      username.value=localStorage.getItem('username')
      socket.send('ENTER',{
         name:username.value,
         avatar: Avatar,
         ticket:'TICKET',
         meetingId: route.query.meetingId
      })
    }

   init()

   function handleEmoji(emoji){
    
  pcMap.forEach((item,fromId)=>{
    const {channel}=item
  
    channel.send(
      JSON.stringify({
        code:'TEXT',
        data:{
          content:emoji
        }
      })
    )
   
   
  })
  messageList.value.push({
        id:`IM_${Math.random()*100000}`,
        name:username,
        content: emoji,
      })
      if(messageList.value.length>10){
        messageList.value.splice(0,1)
      }
}

//创建连接轨道
function createRTCPeerConnection({fromId}){
 const  pc=new RTCPeerConnection()
 const channel=pc.createDataChannel('chat',{negotiated:true,id:1})
 channel.onmessage=(event)=>{
  console.log(event.data)
   const {code,data}=JSON.parse(event.data)
   if(code==='TEXT'){
      messageList.value.push({
        id:`IM_${Math.random()*100000}`,
        content: data.content,
      })
      if(messageList.value.length>10){
        messageList.value.splice(0,1)
      }
   }
 }
 pcMap.set(fromId,{pc,fromId,channel})
  //监听协商的事件
  pc.onnegotiationneeded=async e =>{
  
    //自动生成offer
    await pc.setLocalDescription();
    const offer= pc.localDescription
    socket.send('OFFER',{
      targetId: fromId,
      description:offer,

    });
  }
  
  const tracks=baseStream.getTracks();
  //将音视频的轨道添加到连接上
  tracks.forEach((track)=>pc.addTrack(track,baseStream))
  //监听对等连接音视频轨道的变化
  pc.ontrack=(e)=>{
    const member=memberList.value.find(item=>item.uuid===fromId)
     if(e.track.kind==='audio'){
        //音频可视化
     }
     if(e.track.kind==='video'){
    
     }
     if (member) {
            member.videoFlag = true;  // 开启视频标志
        }
     const remote=document.querySelector(`#im_${member.uuid}`)
  
     
      remote.srcObject=e.streams[0]
    

    
     
  }
  //监听ICE候选地址事件（网络信息）
  pc.onicecandidate=e=>{
    if(e.candidate){
      //必须要加判空
      socket.send('CANDIDATE',{
        targetId: fromId,
        candidate:e.candidate
      })
      
    }
  }
  return pc
}
//监听enter事件
socket.addEventHandler('ENTER',(data)=>{
   const {name ,avatar,fromId,meetingId}=data
   memberList.value.push({name,avatar,uuid:fromId})
    
   //创建webrtc的连接
   createRTCPeerConnection({fromId})

});

//监听offer事件
socket.addEventHandler('OFFER',async (result)=>{
  const { fromId, description } = result;
   const item=pcMap.get(fromId)
   let pc
   if(item){
     pc=item.pc
    await pc.setRemoteDescription(description);
   }else{
    // 此处有修改，加了pc=
     pc=createRTCPeerConnection({ fromId });
      await pc.setRemoteDescription(description);
   }
   //创建answer ，发送answer（answer就是offer只是叫法不同）
   await pc.setLocalDescription();
   const answer=pc.localDescription
  //  socket.send('ANSWER',{
  //   target: fromId,
  //   description: answer

  //  })
  const data = {
      targetId: fromId,
      description: pc.localDescription,
    };
    socket.send('ANSWER', data);

})
  /**
   * 接收ANSWER
   */
socket.addEventHandler('ANSWER', async (result)=>{
  const { fromId, description } = result;
  const {pc}=pcMap.get(fromId)
  await pc.setRemoteDescription(description);

})
 /**
   * 接收CANDIDATE
   */
socket.addEventHandler('CANDIDATE',async (result)=>{
  if(result){
    const { fromId, candidate } = result;
    const {pc}=pcMap.get(fromId)
    await pc.addIceCandidate(candidate);

  }
})

  /**
   * 监听成员挂断
   */
   socket.addEventHandler('ANGUP', function (result) {
    const { fromId } = result;
    // 关闭连接
    const { pc, channel } = pcMap.get(fromId);
    pc?.close();
    pcMap.delete(fromId);
    const index = memberList.value.findIndex((v) => v.uuid === fromId);
    if (index !== -1) {
      const item = memberList.value[index];
      if (item.animationId) {
        cancelAnimationFrame(item.animationId);
      }
      memberList.value.splice(index, 1);
    }
  });

  /**
   * 挂断成功
   */
  socket.addEventHandler('HANGUP_SUCCESS', function () {
    pcMap.forEach((item, key) => {
      const { pc, channel } = item;
      pc.close();
    });
    pcMap.clear();
    ElMessage.success('关闭成功')
    // $storage.remove(TICKET);
    // emit('hangup');
  });


  </script>
  
  <style scoped lang="scss">
  .container{
    width: 100%;
  height: 100vh;
  background: #202123;
  color: white;
  .content{

    height: calc(100vh - 80px);
    display: flex;
  padding: 15px 15px 0;
  position: relative;
  .self {
    flex: 1;
    height: 100%;
    //border: 1px dashed white;
    .user {
      height: 100%;
      //border: 1px solid #e0e0e0;
      background: #333;
      border-radius: 10px;
      overflow: hidden;
      position: relative;

      video {
        object-fit: cover;
        width: 100%;
        height: 100%;
      }

      .tip {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        color: rgba(255, 255, 255, 0.8);
        font-size: 26px;
        position: absolute;
        top: 0;
        left: 0;
      }
    }
  }
  .member-list{
     margin-left: 15px;
     .member-item{
      background: #4a4949;
      border-radius: 8px;
      video{
      width: 300px;
      height: 157px;
    }
     }
    
  }
  }
  .footer{
    .middle {
    height: 80px;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 15px;

    .item {
      background: #343537;
      width: 50px;
      height: 50px;
      border-radius: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      font-size: 26px;
      &:hover {
        background: rgba(255, 255, 255, 0.3);
      }

      &.hang-up {
        background: #dd362e;

        &:hover {
          background: rgba(#dd362e, .8);
        }

        //border-radius: 30px;
        //width: 80px;
      }
    }
  }
  }
  .message-wrapper{
    position: absolute;
    
    left:25px;
    bottom:10px;

 
    .msg-item{
      margin-bottom: 3px;
    }

  }
  .item {
      background: #343537;
      width: 50px;
      height: 50px;
      border-radius: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      font-size: 26px;
      &:hover {
        background: rgba(255, 255, 255, 0.3);
      }

      &.hang-up {
        background: #dd362e;

        &:hover {
          background: rgba(#dd362e, .8);
        }

        //border-radius: 30px;
        //width: 80px;
      }
    }
  }

  </style>
  